package com.pkk.cloud.support.admin.controller.interior.client;

import com.github.pagehelper.PageInfo;
import com.pkk.cloud.support.admin.bo.ClientSecurityHandleBo;
import com.pkk.cloud.support.admin.dto.req.client.OauthClientAddReqDto;
import com.pkk.cloud.support.admin.dto.req.client.OauthClientDelReqDto;
import com.pkk.cloud.support.admin.dto.req.client.OauthClientIdReqDto;
import com.pkk.cloud.support.admin.dto.req.client.OauthClientPageReqDto;
import com.pkk.cloud.support.admin.dto.req.client.OauthClientUpdateReqDto;
import com.pkk.cloud.support.admin.dto.req.client.OauthServerClientIdReqDto;
import com.pkk.cloud.support.admin.dto.req.client.OauthVisitClientBindClientScopeReqDto;
import com.pkk.cloud.support.admin.dto.req.client.OauthVisitClientReqDto;
import com.pkk.cloud.support.admin.dto.req.scope.OauthScopeAddReqData;
import com.pkk.cloud.support.admin.dto.resp.client.OauthClientDetailRespDto;
import com.pkk.cloud.support.admin.dto.resp.server.OauthServerClientByClientVistiRespDto;
import com.pkk.cloud.support.admin.dto.resp.server.OauthServerClientScopeByClientRespDto;
import com.pkk.cloud.support.admin.service.PenguinSysClientScopeBusinessService;
import com.pkk.cloud.support.admin.utils.ClientSecurityUtil;
import com.pkk.cloud.support.oauth2.client.aspect.annotation.PreAuth;
import com.pkk.cloud.support.oauth2.client.detail.client.entity.PenguinOauthClient;
import com.pkk.cloud.support.oauth2.common.utils.SecurityUtils;
import com.pkk.components.rpc.request.CommonRequest;
import com.pkk.components.rpc.request.PagedQueryRequest;
import com.pkk.components.rpc.response.CommonResponse;
import com.pkk.components.rpc.response.util.ResponseUtil;
import java.util.List;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @description: 客户端/客户访问端控制器
 * @author: peikunkun
 * @create: 2020-03-30 10:49
 **/
@Slf4j
@RestController
@RequestMapping("/oauth/client")
public class OauthClientController {

  @Resource
  private PenguinSysClientScopeBusinessService penguinSysClientScopeBusinessService;


  /**
   * @Description: 新增OAuth2客户端
   * @return: com.pkk.components.rpc.response.CommonResponse<java.lang.Boolean>
   * @Author: peikunkun
   * @Date: 2020/3/30 0030 上午 10:51
   */
  @PreAuth
  @PostMapping(value = "/add")
  public CommonResponse<Boolean> add(@Validated @RequestBody CommonRequest<OauthClientAddReqDto> request) {
    final OauthClientAddReqDto body = request.getBody();
    if (null == body) {
      return ResponseUtil.error("必要参数不存在");
    }

    //数据转换
    final PenguinOauthClient client = new PenguinOauthClient();
    BeanUtils.copyProperties(body, client);
    if (ArrayUtils.isNotEmpty(body.getGrantTypeArr())) {
      client.setGrantType(StringUtils.join(body.getGrantTypeArr(), ","));
    }

    //加密操作
    final ClientSecurityHandleBo clientSecurityHandleBo = ClientSecurityUtil
        .bCryptPassword(client.getClientId(), client.getClientOriginalSecret());
    client.setClientSecret(clientSecurityHandleBo.getClientSecret());
    client.setClientCode(clientSecurityHandleBo.getClientCode());

    //验证客户端是否存在
    boolean exists = penguinSysClientScopeBusinessService
        .countClientExists(client.getClientType(), client.getClientId(), client.getOwnServerId(), null);
    if (exists) {
      return ResponseUtil.error("[" + client.getClientId() + "]该客户端已经存在");
    }

    //保存操作
    boolean result = penguinSysClientScopeBusinessService.saveOauth2Client(client);
    if (result) {
      return ResponseUtil.success();
    } else {
      return ResponseUtil.error("保存客户端[" + client.getClientId() + "]信息失败");
    }
  }


  /**
   * @Description: 依据id查询客户端详细信息
   * @Param: request
   * @return: com.pkk.components.rpc.response.CommonResponse<com.pkk.cloud.support.admin.dto.resp.client.OauthClientDetailRespDto>
   * @Author: peikunkun
   * @Date: 2020/4/5 0005 下午 3:12
   */
  @PreAuth
  @PostMapping(value = "/findClientById")
  public CommonResponse<OauthClientDetailRespDto> findClientById(
      @Validated @RequestBody CommonRequest<OauthClientIdReqDto> request) {
    return ResponseUtil.success(penguinSysClientScopeBusinessService.findClientById(request.getBody()));
  }


  /**
   * @Description: 查询客户端/客户访问端列表信息
   * @Param: request
   * @return: com.pkk.components.rpc.response.CommonPageResponse<com.pkk.cloud.support.admin.dto.resp.client.OauthClientPageRespDto>
   * @Author: peikunkun
   * @Date: 2020/3/30 0030 下午 3:26
   */
  @PreAuth
  @PostMapping(value = "/list")
  public CommonResponse<PageInfo<OauthClientDetailRespDto>> list(@Validated @RequestBody
      PagedQueryRequest<OauthClientPageReqDto> request) {
    return ResponseUtil
        .success(penguinSysClientScopeBusinessService.findOauthClientPage(request.getPage(), request.getBody()));
  }


  /**
   * @Description: 删除客户端操作
   * @Param: request
   * @return: com.pkk.components.rpc.response.CommonResponse<java.lang.Boolean>
   * @Author: peikunkun
   * @Date: 2020/4/1 0001 下午 4:03
   */
  @PreAuth
  @PostMapping(value = "/del")
  public CommonResponse<Boolean> del(@Validated @RequestBody CommonRequest<OauthClientDelReqDto> request) {
    final String userId = SecurityUtils.getUserId();
    return ResponseUtil
        .success(penguinSysClientScopeBusinessService.updateOauthClientCloseById(request.getBody(), userId));
  }


  /**
   * @Description: 更新客户端信息依据id
   * @Param: request
   * @return: com.pkk.components.rpc.response.CommonResponse<java.lang.Boolean>
   * @Author: peikunkun
   * @Date: 2020/4/1 0001 下午 6:33
   */
  @PreAuth
  @PostMapping(value = "update")
  public CommonResponse<Boolean> update(@Validated @RequestBody CommonRequest<OauthClientUpdateReqDto> request) {
    //数据转换
    final OauthClientUpdateReqDto body = request.getBody();
    final PenguinOauthClient client = new PenguinOauthClient();
    BeanUtils.copyProperties(body, client);
    if (ArrayUtils.isNotEmpty(body.getGrantTypeArr())) {
      client.setGrantType(StringUtils.join(body.getGrantTypeArr(), ","));
    }

    //是否存在客户端
    final boolean exists = penguinSysClientScopeBusinessService
        .countClientExists(client.getClientType(), client.getClientId(), client.getOwnServerId(), client.getId());
    if (exists) {
      return ResponseUtil.error("客户端[".concat(client.getClientId()).concat("]已经存在,请更换"));
    }

    //获取client信息
    PenguinOauthClient oauthClient = penguinSysClientScopeBusinessService.getOauthClientById(client.getId());
    if (StringUtils.isNotBlank(client.getClientOriginalSecret()) && !client.getClientOriginalSecret()
        .equals(oauthClient.getClientOriginalSecret())) {
      //加密操作
      final ClientSecurityHandleBo clientSecurityHandleBo = ClientSecurityUtil
          .bCryptPassword(client.getClientId(), client.getClientOriginalSecret());
      client.setClientSecret(clientSecurityHandleBo.getClientSecret());
      client.setClientCode(clientSecurityHandleBo.getClientCode());
    }
    return ResponseUtil.success(penguinSysClientScopeBusinessService.updateOauthClientById(client));
  }


  /**
   * @Description: 获取客户端的服务组以及服务组下面的客户端信息【服务端->客户端】
   * @Author: peikunkun
   * @Date: 2020/4/9 下午7:12
   */
  @PreAuth
  @PostMapping("getBindServerClientByClientId")
  public CommonResponse<List<OauthServerClientScopeByClientRespDto>> getBindServerClientByClientId(
      @Validated @RequestBody CommonRequest<OauthServerClientIdReqDto> request) {
    return ResponseUtil
        .success(penguinSysClientScopeBusinessService.getBindServerClientByClientId(request.getBody().getClientId()));
  }


  /**
   * @Description: 绑定服务关联
   * @Param: requestInfo
   * @return: com.pkk.components.rpc.response.CommonResponse<java.lang.String>
   * @Author: peikunkun
   * @Date: 2020/4/22 0022 下午 5:22
   */
  @PreAuth
  @PostMapping("bindClientScope")
  public CommonResponse bindClientScope(
      @RequestBody @Validated CommonRequest<OauthScopeAddReqData> requestInfo) {
    penguinSysClientScopeBusinessService
        .bindClientScope(requestInfo.getBody().getClientId(), requestInfo.getBody().getScopes());
    return ResponseUtil.success();
  }


  /**
   * @Description: 获取访问客户端的客户端绑定信息
   * @Param: request
   * @return: com.pkk.components.rpc.response.CommonResponse
   * @Author: peikunkun
   * @Date: 2020/4/24 0024 上午 10:07
   */
  @PreAuth
  @PostMapping("findVisitClientBindInfo")
  public CommonResponse<List<OauthServerClientByClientVistiRespDto>> findVisitClientBindInfo(
      @RequestBody @Validated CommonRequest<OauthVisitClientReqDto> request) {
    return ResponseUtil
        .success(penguinSysClientScopeBusinessService.findVisitClientBindInfo(request.getBody().getVisitClientId()));
  }


  /**
   * @Description: 访问客户端绑定客户端scope
   * @Param: request
   * @return: com.pkk.components.rpc.response.CommonResponse<java.util.List < com.pkk.cloud.support.admin.dto.resp.server.OauthServerClientByClientVistiRespDto>>
   * @Author: peikunkun
   * @Date: 2020/4/24 0024 上午 10:27
   */
  @PreAuth
  @PostMapping("visitClientBindClientScope")
  public CommonResponse<Boolean> visitClientBindClientScope(
      @RequestBody @Validated CommonRequest<OauthVisitClientBindClientScopeReqDto> request) {
    return ResponseUtil.success(penguinSysClientScopeBusinessService
        .bindClientScope(request.getBody().getVisitClientId(), request.getBody().getClients()));
  }


}
